<?php

namespace App\Task\Stat;

use App\Model\AppChannel;
use App\Model\CallBase;
use App\Model\CoinLog;
use App\Model\PayOrder;
use App\Model\Stat\StatDaily;
use App\Model\Stat\StatDailyCall;
use App\Model\Stat\StatDailyHostInfo;
use App\Model\User;
use App\Model\UserActLog;
use App\Model\UserCoin;
use App\Model\UserProfile;
use App\Model\UserProfilePersonal;
use App\Model\VideoCall;
use App\Model\VoiceCall;
use Hyperf\Crontab\Annotation\Crontab;

/**
 * 每日统计
 * @Crontab(name="StatDailyTask", rule="5,15,35,50 *\/1 * * *", callback="execute", memo="每日数据统计", singleton=false)
 */
class StatDailyTask
{
    /**
     * @return void
     */
    public function execute()
    {
        log_info(__CLASS__ . "==Start==" . date('Y-m-d H:i:s'));
        $this->runDaily();
        // for ($day = 40; $day > 0; $day--) {
        //     $this->runDaily($day);
        // }
    }

    /**
     * 日报相关数据
     */
    function runDaily($day = 0)
    {
        $channels = AppChannel::getAllChannels();
        //一天前5分钟内
        if (time() - strtotime(date('Y-m-d')) < 1800) {
            $day++;
        }
        $this->dt = date('Y-m-d', strtotime("-{$day} day"));
        $nextDay = $day - 1;
        $this->endTime = date('Y-m-d', strtotime("-{$nextDay} day"));
        $channels[] = 'all';
        foreach ($channels as $channel) {
            //日报表
            $this->beginStat($channel);
        }
        //话单统计
        $this->beginStatCall(VideoCall::CALL_TYPE);
        $this->beginStatCall(VoiceCall::CALL_TYPE);
    }

    /**
     * 获取模型
     */
    function getModel($statClass, $channel = '')
    {
        $where = ['dt' => $this->dt];
        if ($channel) $where['channel'] = $channel;
        $model = $statClass::where($where)->first();
        if (!$model) $model = new $statClass();
        return $model;
    }

    /**
     * 获取话单模型
     */
    function getCallModel($statClass, $callType = -1, $subType = 0)
    {
        $where = [
            'dt' => $this->dt,
            'call_type' => $callType,
            'call_subtype' => $subType
        ];
        $model = $statClass::where($where)->first();
        if (!$model) $model = new $statClass();
        return $model;
    }

    /**
     * 开始统计-日报表
     */
    function beginStat($channel = '')
    {
        $model = $this->getModel(StatDaily::class, $channel);
        if (!$model) return false;
        $model->dt = $this->dt;
        $model->channel = $channel;
        $channel == 'all' && $channel = '';
        // log_info(__CLASS__ . "==beginStat1111=={$this->dt}=={$channel}");
        $model->active_total = UserActLog::checkActiveCount([], $this->dt, $this->endTime, $channel);
        $model->active_male = UserActLog::checkCount(1, -1, $this->dt, $this->endTime, $channel);
        $model->active_host = UserActLog::checkCount(-1, UserProfile::ROLE_HOST, $this->dt, $this->endTime, $channel);
        $model->reg_total = User::getRegUsers($this->dt, $this->endTime, 'count', $channel);
        // log_info(__CLASS__ . "==beginStat2222=={$this->dt}=={$channel}");
        $model->reg_male = UserProfile::getRegCount(1, -1, $this->dt, $this->endTime, $channel);
        $model->reg_female = UserProfile::getRegCount(0, -1, $this->dt, $this->endTime, $channel);
        $model->reg_host = UserProfile::getRegCount(0, UserProfile::ROLE_HOST, $this->dt, $this->endTime, $channel);
        $model->reg_avatar_vrfied = UserProfile::getRegCount(0, -1, $this->dt, $this->endTime, $channel, 'count', 1);
        $model->reg_real_name = UserProfilePersonal::getRealNameTotalByDay($this->dt, $this->endTime, $channel);
        $model->recharge_num = PayOrder::getRechargeCount([], $this->dt, $this->endTime, $channel);
        $model->recharge_coin = PayOrder::getRechargeCoin([], $this->dt, $this->endTime, $channel);
        $model->send_coin = PayOrder::getRechargeCoin([], $this->dt, $this->endTime, $channel, 'send_coin');
        $model->recharge_rmb = PayOrder::getRechargeCoin([], $this->dt, $this->endTime, $channel, 'rmb');
        $regUserIds = User::getRegUsers($this->dt, $this->endTime, 'userId', $channel);
        $model->new_recharge_num = empty($regUserIds) ? 0 : PayOrder::getRechargeCount($regUserIds, $this->dt, $this->endTime, $channel);
        //主播总收入（计算总渠道的）
        $channel == '' && $model->income_coin = CoinLog::getTotalIncome(StatDailyHostInfo::getActiveHosts($this->dt), $this->dt, $this->endTime);
        $channel == '' && $model->free_income_coin = CoinLog::getTotalIncome(StatDailyHostInfo::getActiveHosts($this->dt), $this->dt, $this->endTime, CoinLog::FREE_INCOME);
        // $model->new_recharge_coin = empty($regUserIds) ? 0 : PayOrder::getRechargeCoin($regUserIds, $this->dt, $this->endTime, $channel);
        $model->new_recharge_rmb = empty($regUserIds) ? 0 : PayOrder::getRechargeCoin($regUserIds, $this->dt, $this->endTime, $channel, 'rmb');
        $model->consume_num = CoinLog::getConsumeCount($this->dt, $this->endTime, 'count', $channel);
        $model->consume_coin = CoinLog::getConsumeCount($this->dt, $this->endTime, 'coin', $channel);
        $model->withdraw_num = CoinLog::getConsumeCount($this->dt, $this->endTime, 'count', $channel, CoinLog::FROM_WITHDRAW);
        $model->withdraw_coin = CoinLog::getConsumeCount($this->dt, $this->endTime, 'coin', $channel, CoinLog::FROM_WITHDRAW);
        $model->total_user_num = UserProfile::getRegCount(-1, -1, '', $this->endTime, $channel);
        $model->total_host_num = UserProfile::getRegCount(-1, UserProfile::ROLE_HOST, '', $this->endTime, $channel);
        $model->total_recharge_coin = UserCoin::getTotalRechargeCoin();
        $model->total_order_coin = PayOrder::getRechargeCoin() + PayOrder::getRechargeCoin([], '', '', '', 'send_coin');
        log_info(__CLASS__ . "==beginStat=={$this->dt}=={$channel}");
        $model->saveOrFail();
    }

    /**
     * 话单日报
        $table->tinyInteger('call_type')->default(-1)->comment('话单类型');
        $table->integer('call_num')->default(0)->comment('总话单');
        $table->integer('success_num')->default(0)->comment('成功话单');
        $table->integer('caller_num')->default(0)->comment('总呼叫人数');
        $table->integer('receiver_num')->default(0)->comment('总被叫人数');
        $table->integer('success_caller_num')->default(0)->comment('成功拨打人数');
        $table->integer('success_receiver_num')->default(0)->comment('成功接听人数');
        $table->integer('total_call_time')->default(0)->comment('话单总时长');
        $table->integer('call_num_fail')->default(0)->comment('失败话单数');
        $table->integer('call_num_noanswer')->default(0)->comment('无人接听话单数');
        $table->integer('call_num_hangup')->default(0)->comment('主叫挂断');
        $table->integer('call_num_reject')->default(0)->comment('被叫拒绝');
        $table->integer('call_num_err')->default(0)->comment('系统异常挂断');
     */
    function beginStatCall($callType = -1)
    {
        $callCls = $callType == -1 ? CallBase::class : ($callType == 1 ? VideoCall::class : VoiceCall::class);
        foreach (StatDailyCall::SUB_TYPE as $type => $subType) {
            $model = $this->getCallModel(StatDailyCall::class, $callType, $type);
            if (!$model) continue;
            $model->dt = $this->dt;
            $model->call_type = $callType;
            $model->call_subtype = $type;
            $callFrom = $subType['from'];
            $model->call_num = $callCls::getCallNum('all', $this->dt, $this->endTime, $callFrom);
            $model->success_num = $callCls::getCallNum('success_num', $this->dt, $this->endTime, $callFrom);
            $model->caller_num = $callCls::getCallNum('caller_num', $this->dt, $this->endTime, $callFrom);
            $model->receiver_num = $callCls::getCallNum('receiver_num', $this->dt, $this->endTime, $callFrom);
            $model->success_caller_num = $callCls::getCallNum('success_caller_num', $this->dt, $this->endTime, $callFrom);
            $model->success_receiver_num = $callCls::getCallNum('success_receiver_num', $this->dt, $this->endTime, $callFrom);
            $model->total_call_time = $callCls::getCallNum('total_call_time', $this->dt, $this->endTime, $callFrom);
            $model->total_call_minutes = $callCls::getCallNum('total_call_minutes', $this->dt, $this->endTime, $callFrom);
            $model->call_num_fail = $callCls::getCallNum('call_num_fail', $this->dt, $this->endTime, $callFrom);
            $model->call_num_noanswer = $callCls::getCallNum('call_num_noanswer', $this->dt, $this->endTime, $callFrom);
            $model->call_num_hangup = $callCls::getCallNum('call_num_hangup', $this->dt, $this->endTime, $callFrom);
            $model->call_num_reject = $callCls::getCallNum('call_num_reject', $this->dt, $this->endTime, $callFrom);
            $model->call_num_err = $callCls::getCallNum('call_num_err', $this->dt, $this->endTime, $callFrom);
            $model->saveOrFail();
        }
        // log_info(__CLASS__ . "==beginStatCall==" . json_encode($model));
        return;
    }
}
